package com.spice.service.controller;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.spice.common.constant.PermissionConstant;
import com.spice.common.exception.SpiceException;
import com.spice.common.model.BaseEntity;
import com.spice.common.result.Response;
import com.spice.common.result.ResultCodeEnum;
import com.spice.common.util.PermissionUtil;
import com.spice.service.entity.form.BackupForm;
import com.spice.service.entity.form.EditEntityForm;
import com.spice.service.entity.form.RollbackForm;
import com.spice.service.entity.job.BackupJob;
import com.spice.service.entity.job.JobExecutor;
import com.spice.service.entity.job.RollbackJob;
import com.spice.service.entity.pojo.BackupInfo;
import com.spice.service.service.BackupInfoService;
import com.spice.service.util.ShiroUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/api/backup")
public class BackupController {
    @Autowired
    BackupInfoService backupInfoService;


    @ApiOperation("获取所有表备份信息")
    @PostMapping(value = "/getAllBackup", produces = "application/json;charset=UTF-8")
    public Response getAllBackup() {
        if (!ShiroUtil.isAuthenticated()) {
            return Response.setResult(ResultCodeEnum.NO_AUTHENTICATION);
        }
        List<BackupInfo> list = backupInfoService.list(null);
        return Response.ok().data("records", list);
    }

    @ApiOperation("获取目标表备份信息")
    @PostMapping(value = "/getBackup/{tableName}", produces = "application/json;charset=UTF-8")
    public Response getBackup(@PathVariable("tableName") String tableName) {
        if (!ShiroUtil.isAuthenticated()) {
            return Response.setResult(ResultCodeEnum.NO_AUTHENTICATION);
        }
        List<BackupInfo> list = backupInfoService.list(new LambdaQueryWrapper<BackupInfo>()
                .eq(BackupInfo::getTableName, tableName));
        return Response.ok().data("records", list);
    }


    @ApiOperation("备份目标表")
    @PostMapping(value = "/backup/{tableName}", produces = "application/json;charset=UTF-8")
    public Response backup(@PathVariable("tableName") String tableName,
                           @RequestBody BackupForm backupForm) {
        if (!ShiroUtil.isAuthenticated()) {
            return Response.setResult(ResultCodeEnum.NO_AUTHENTICATION);
        }
        if (!ShiroUtil.checkPermission(PermissionUtil.combinePermission(
                tableName,
                PermissionConstant.BACKUP_PERMISSION))) {
            return Response.setResult(ResultCodeEnum.NO_PERMISSION);
        }

        BackupJob backupJob = new BackupJob(tableName,
                backupForm.getDetails(),
                backupInfoService);
        JobExecutor.addJob(backupJob);

        return Response.ok().data("jobId", backupJob.getId());
    }


    @ApiOperation("回溯目标表")
    @PostMapping(value = "/rollback", produces = "application/json;charset=UTF-8")
    public Response rollback(@RequestBody RollbackForm rollbackForm) {
        if (!ShiroUtil.isAuthenticated()) {
            return Response.setResult(ResultCodeEnum.NO_AUTHENTICATION);
        }
        BackupInfo backupInfo = backupInfoService.getById(rollbackForm.getId());

        if (!ShiroUtil.checkPermission(PermissionUtil.combinePermission(
                backupInfo.getTableName(),
                PermissionConstant.BACKUP_MANAGEMENT_PERMISSION))) {
            return Response.setResult(ResultCodeEnum.NO_PERMISSION);
        }

        RollbackJob rollbackJob = new RollbackJob(backupInfo.getBackupFileName());

        JobExecutor.addJob(rollbackJob);

        return Response.ok().data("rollbackJob", rollbackJob.getId());
    }

    @ApiOperation("编辑目标表的备份（tableName）（remove、update）")
    @PostMapping(value = "/edit/{tableName}/{method}", produces = "application/json;charset=UTF-8")
    public Response backupManagement(@PathVariable("method") String method,
                                     @PathVariable("tableName") String tableName,
                                     @RequestBody EditEntityForm<BackupInfo> editEntityForm) {
        if (!ShiroUtil.isAuthenticated()) {
            return Response.setResult(ResultCodeEnum.NO_AUTHENTICATION);
        }
        if (!ShiroUtil.checkPermission(PermissionUtil.combinePermission(
                tableName,
                PermissionConstant.BACKUP_MANAGEMENT_PERMISSION))) {
            return Response.setResult(ResultCodeEnum.NO_PERMISSION);
        }

        BackupInfo backupInfo = editEntityForm.getT().cleanup();
        Long id = editEntityForm.getId();
        if ("remove".equals(method)) {
            // 删除备份
            BackupInfo removedBackupInfo = backupInfoService.getById(id);
            if (removedBackupInfo == null) {
                throw new SpiceException().message("该id不存在");
            }
            if (!tableName.equals(removedBackupInfo.getTableName())) {
                throw new SpiceException().message("删除的备份信息与参数不符");
            }
            if (backupInfoService.removeById(id)) {
                return Response.ok().message("删除成功").data("backupInfo", removedBackupInfo);
            } else {
                return Response.ok().message("删除失败");
            }
        } else if ("update".equals(method)) {
            // 更新备份
            BackupInfo updateBackupInfo = backupInfoService.getById(id);
            if (updateBackupInfo == null) {
                throw new SpiceException().message("该id不存在");
            }
            if (!tableName.equals(updateBackupInfo.getTableName())) {
                throw new SpiceException().message("修改的备份信息与参数不符");
            }
            backupInfo.setId(id);
            if (backupInfoService.updateById(backupInfo)) {
                return Response.ok().message("更新成功").data("backupInfo", backupInfo);
            } else {
                return Response.ok().message("更新失败");
            }
        }
        return Response.ok();
    }

}
